package com.ht.api.service;

import java.util.ArrayList;
import java.util.List;

import javax.sql.DataSource;

import com.ht.api.db.Db;
import com.ht.api.db.DbList;
import com.ht.api.db.Entity;
import com.ht.api.db.exception.HtException;
import com.ht.api.open.OpenUtil;

import cn.hutool.core.util.StrUtil;
import cn.hutool.json.JSONObject;
import cn.hutool.json.JSONUtil;

/**
 * 接粉相关service
 * @author asq
 * @createTime 2025年4月2日 20:10:13
 */
public class FanService {
	/** 接口ID：配置客户联系「联系我」方式 */
	private static final long API_ID_CONTACT_WAY_ADD = 1900130323056955392L;
	/** 接口ID：更新企业已配置的「联系我」方式 */
	private static final long API_ID_CONTACT_WAY_EDIT = 1900131140698771456L;
	/** 接口ID：删除企业已配置的「联系我」方式 */
	private static final long API_ID_CONTACT_WAY_DEL = 1900131364737519616L;
	
	/** 接口ID：配置客户群进群方式 */
	private static final long API_ID_CHAT_WAY_ADD = 1900132334599016448L;
	/** 接口ID：更新客户群进群方式配置 */
	private static final long API_ID_CHAT_WAY_EDIT = 1900132756453724160L;
	/** 接口ID：删除客户群进群方式配置 */
	private static final long API_ID_CHAT_WAY_DEL = 1900132983659171840L;
	/** 接口ID：获取客户群进群方式配置 */
	private static final long API_ID_CHAT_WAY_QUERY = 1900132539570458624L;
	
	/** 接口ID：创建获客链接 */
	private static final long API_ID_CUSTOMER_LINK_ADD = 1896832030612787200L;
	/** 接口ID：编辑获客链接 */
	private static final long API_ID_CUSTOMER_LINK_EDIT = 1896834036354125824L;
	/** 接口ID：删除获客链接 */
	private static final long API_ID_CUSTOMER_LINK_DEL = 1896834425233215488L;



	
	/** 接口ID：查询剩余使用量 */
	private static final long API_ID_QUOTA_QUERY = 1896836201579679744L;

	/**
	 * 新增接粉外部数据
	 * @param ds 数据源
	 * @param appId 应用ID
	 * @param positionId 渠道广告位ID
	 * @param positionName 渠道广告位名称
	 * @param state 渠道广告位自定义渠道
	 * @param inType 进粉方式
	 * @param ids 接粉组关联ID列表
	 */
	public static String add(DataSource ds, String appId, String positionId, String positionName,
			String state, String inType, List<String> ids) {
		switch (inType) {
		case "wx_contact_way":
			return addWithContactWay(ds, appId, positionId, positionName, state, ids);

		case "wx_chat_way":
			return addWithChatWay(ds, appId, positionId, positionName, state, ids);

		case "wx_customer_link":
			return addWithCustomerLink(ds, appId, positionId, positionName, state, ids);
		}

		return null;
	}
	
	/**
	 * 修改接粉外部数据
	 * @param ds 数据源
	 * @param appId 应用ID
	 * @param positionId 渠道广告位ID
	 * @param positionName 渠道广告位名称
	 * @param state 渠道广告位自定义渠道
	 * @param inType 进粉方式
	 * @param ids 接粉组关联ID列表
	 */
	public static void edit(DataSource ds, String appId, String positionId, String positionName, 
			String state, String inType, List<String> ids) {
		switch (inType) {
		case "wx_contact_way":
			editWithContactWay(ds, appId, positionId, positionName, state, ids);
			break;
			
		case "wx_chat_way":
			editWithChatWay(ds, appId, positionId, positionName, state, ids);
			break;
			
		case "wx_customer_link":
			editWithCustomerLink(ds, appId, positionId, positionName, state, ids);
			break;

		default:
			break;
		}
	}
	
	/**
	 * 删除接粉外部数据
	 * @param ds 数据源
	 * @param appId 应用ID
	 * @param positionId 渠道广告位ID
	 * @param inType 进粉方式
	 */
	public static void del(DataSource ds, String appId, String positionId, String inType) {
		switch (inType) {
		case "wx_contact_way":
			delWithContactWay(ds, appId, positionId);
			break;
			
		case "wx_chat_way":
			delWithChatWay(ds, appId, positionId);
			break;
			
		case "wx_customer_link":
			delWithCustomerLink(ds, appId, positionId);
			break;

		default:
			break;
		}
	}
	
	/**
	 * 获取接粉组关联的客服ID列表或者群ID列表
	 * @param ds 数据源
	 * @param fanTeamId 接粉组ID
	 * @return
	 */
	public static List<String> getRelIds(DataSource ds, String fanTeamId){
		int teamType = Db.createSqlParser("fan_team").select("team_type").val(ds, Integer.class);
		boolean isUserRel = teamType == 1;
		
		List<String> oldRelIds = new ArrayList<>();
		DbList relList = null;
		if (isUserRel) {
			relList = Db.createSqlParser("fan_service_team_relation").select("userid rel")
					.where("team_id", fanTeamId).where("status", 0).query(ds);
		} else {
			relList = Db.createSqlParser("fan_chat_team_relation").select("chat_id rel")
					.where("team_id", fanTeamId).where("status", 0).query(ds);
		}
		relList.stream().forEach(bean -> {
			oldRelIds.add(bean.getStr("rel"));
		});
		
		return oldRelIds;
	}
	
	/**
	 * 刷新获客助手额度
	 * @param ds 数据源
	 * @param appid 应用ID
	 */
	public static void refresh(DataSource ds, String appid) {
		String str = OpenUtil.call(appid, API_ID_QUOTA_QUERY, JSONUtil.createObj());
		JSONObject obj = JSONUtil.parseObj(str);
		if (obj.getInt("errcode") == 0) {
			Entity quota = Db.createSqlParser("wx_customer_link_quota").where("appid", appid).findOne(ds);
			if (quota == null) {
				quota = Entity.create("wx_customer_link_quota");
				quota.set("appid", appid);
				quota.set("total", 0);
				quota.set("balance", 0);
			}
			quota.set("total", obj.getInt("total") - quota.getInt("total"));
			quota.set("balance", obj.getInt("balance") - quota.getInt("balance"));
			Db.insert(ds, quota);
		} else {
			throw new HtException("查询获客助手额度企微接口返回错误：" + obj.getStr("errmsg"));
		}	
	}
	
	/**
	 * 新增联系我
	 * @param ds 数据源
	 * @param appId 应用ID
	 * @param positionId 渠道广告位ID
	 * @param positionName 渠道广告位名称
	 * @param state 渠道广告位自定义渠道
	 * @param ids 接粉组关联ID列表
	 */
	private static String addWithContactWay(DataSource ds, String appId, String positionId,
			String positionName, String state, List<String> ids) {
		String oldConfigId = Db.createSqlParser("wx_contact_way").select("config_id")
				.where("position_id", positionId).val(ds);
		if (StrUtil.isNotBlank(oldConfigId)) {
			throw new HtException("联系我已存在！");
		}
		
		// 调用企微接口
		JSONObject wwxParam = JSONUtil.createObj();
		wwxParam.set("type", 2);
		wwxParam.set("scene", 2);
		wwxParam.set("skip_verify", true);
		wwxParam.set("state", state);
		wwxParam.set("user", ids);
		wwxParam.set("is_exclusive", true);
		String str = OpenUtil.call(appId, API_ID_CONTACT_WAY_ADD, wwxParam);
		
		// 本地数据库
		JSONObject obj = JSONUtil.parseObj(str);
		if (obj.getInt("errcode") == 0) {
			Entity wxContactWay = Db.createEntity("wx_contact_way");
			wxContactWay.set("state", state);
			wxContactWay.set("position_id", positionId);
			wxContactWay.set("appid", appId);
			wxContactWay.set("type", 2);
			wxContactWay.set("scene", 2);
			wxContactWay.set("skip_verify", 1);
			wxContactWay.set("is_exclusive", 1);
			wxContactWay.set("config_id", obj.getStr("config_id"));
			wxContactWay.set("qr_code", obj.getStr("qr_code"));
			Db.insert(ds, wxContactWay);
		} else if (obj.getInt("errcode") == 41054) {
			throw new HtException("成员需要是已激活的成员，即成员至少登录过企业微信，且已实名认证！");
		} else {
			throw new HtException("新增联系我企微接口返回错误：" + obj.getStr("errmsg"));
		}

		return obj.getStr("config_id");
	}
	
	/**
	 * 修改联系我
	 * @param ds 数据源
	 * @param appId 应用ID
	 * @param positionId 渠道广告位ID
	 * @param positionName 渠道广告位名称
	 * @param state 渠道广告位自定义渠道
	 * @param ids 接粉组关联ID列表
	 */
	private static void editWithContactWay(DataSource ds, String appId, String positionId, String positionName, 
			String state, List<String> ids) {
		String configId = Db.createSqlParser("wx_contact_way").select("config_id")
				.where("position_id", positionId).val(ds);
		if (StrUtil.isBlank(configId)) {
			throw new HtException("联系我不存在！");
		}
		
		// 调用企微接口
		JSONObject wwxParam = JSONUtil.createObj();
		wwxParam.set("config_id", configId);
		wwxParam.set("user", ids);
		String str = OpenUtil.call(appId, API_ID_CONTACT_WAY_EDIT, wwxParam);
		JSONObject obj = JSONUtil.parseObj(str);
		
		if (obj.getInt("errcode") == 41054) {
			throw new HtException("成员需要是已激活的成员，即成员至少登录过企业微信，且已实名认证！");
		} else if (obj.getInt("errcode") != 0) {
			throw new HtException("修改联系我企微接口返回错误：" + obj.getStr("errmsg"));
		}
	}
	
	/**
	 * 删除联系我
	 * @param ds 数据源
	 * @param appId 应用ID
	 * @param positionId 渠道广告位ID
	 */
	private static void delWithContactWay(DataSource ds, String appId, String positionId) {
		Entity wxContactWay = Db.createSqlParser("wx_contact_way")
				.where("position_id", positionId).findOne(ds);
		if (wxContactWay == null) {
			return ;
		}
		
		// 调用企微接口，删除
		JSONObject wwxParam = JSONUtil.createObj().set("config_id", wxContactWay.getStr("config_id"));
		String str = OpenUtil.call(appId, API_ID_CONTACT_WAY_DEL, wwxParam);
		
		// 本地数据库
		JSONObject obj = JSONUtil.parseObj(str);
		if (obj.getInt("errcode") == 0) {
			Db.delete(ds, wxContactWay);
		} else {
			throw new HtException("删除联系我企微接口返回错误：" + obj.getStr("errmsg"));
		}
	}
	
	/**
	 * 新增加入群聊
	 * @param ds 数据源
	 * @param appId 应用ID
	 * @param positionId 渠道广告位ID
	 * @param positionName 渠道广告位名称
	 * @param state 渠道广告位自定义渠道
	 * @param ids 接粉组关联ID列表
	 */
	private static String addWithChatWay(DataSource ds, String appId, String positionId,
			String positionName, String state, List<String> ids) {
		String oldConfigId = Db.createSqlParser("wx_chat_way").select("config_id")
				.where("position_id", positionId).val(ds);
		if (StrUtil.isNotBlank(oldConfigId)) {
			throw new HtException("加入群聊已存在！");
		}
		
		// 调用企微接口
		JSONObject wwxParam = JSONUtil.createObj();
		wwxParam.set("scene",2);
		wwxParam.set("chat_id_list", ids);
		wwxParam.set("state", state);
		String str = OpenUtil.call(appId, API_ID_CHAT_WAY_ADD, wwxParam);
		
		// 本地数据库
		JSONObject obj = JSONUtil.parseObj(str);
		if (obj.getInt("errcode") == 0) {
			String configId = obj.getStr("config_id");
			
			// 查询加入群聊的详细信息
			String str2 = OpenUtil.call(appId, API_ID_CHAT_WAY_QUERY, JSONUtil.createObj().set("config_id", configId));
			JSONObject obj2 = JSONUtil.parseObj(str2);
			if (obj2.getInt("errcode") == 0) {
				Entity wxChatWay = Db.createEntity("wx_chat_way");
				wxChatWay.set("state", state);
				wxChatWay.set("position_id", positionId);
				wxChatWay.set("appid", appId);
				wxChatWay.set("scene", 2);
				wxChatWay.set("config_id", configId);
				wxChatWay.set("qr_code", obj2.getByPath("join_way.qr_code", String.class));
				Db.insert(ds, wxChatWay);
			} else {
				throw new HtException("查询加入群聊企微接口返回错误：" + obj2.getStr("errmsg"));
			}
		} else {
			throw new HtException("新增加入群聊企微接口返回错误：" + obj.getStr("errmsg"));
		}

		return obj.getStr("config_id");
	}
	
	/**
	 * 修改加入群聊
	 * @param ds 数据源
	 * @param appId 应用ID
	 * @param positionId 渠道广告位ID
	 * @param positionName 渠道广告位名称
	 * @param state 渠道广告位自定义渠道
	 * @param ids 接粉组关联ID列表
	 */
	private static void editWithChatWay(DataSource ds, String appId, String positionId, String positionName, 
			String state, List<String> ids) {
		String configId = Db.createSqlParser("wx_chat_way").select("config_id")
				.where("position_id", positionId).val(ds);
		if (StrUtil.isBlank(configId)) {
			throw new HtException("加入群聊不存在！");
		}
		
		// 调用企微接口
		JSONObject wwxParam = JSONUtil.createObj();
		wwxParam.set("config_id", configId);
		wwxParam.set("scene", 2);
		wwxParam.set("chat_id_list", ids);
		String str = OpenUtil.call(appId, API_ID_CHAT_WAY_EDIT, wwxParam);
		JSONObject obj = JSONUtil.parseObj(str);
		if (obj.getInt("errcode") != 0) {
			throw new HtException("修改加入群聊企微接口返回错误：" + obj.getStr("errmsg"));
		}
	}
	
	/**
	 * 删除加入群聊
	 * @param ds 数据源
	 * @param appId 应用ID
	 * @param positionId 渠道广告位ID
	 */
	private static void delWithChatWay(DataSource ds, String appId, String positionId) {
		Entity wxChatWay = Db.createSqlParser("wx_chat_way")
				.where("position_id", positionId).findOne(ds);
		if (wxChatWay == null) {
			return ;
		}
		
		// 调用企微接口，删除
		JSONObject wwxParam = JSONUtil.createObj().set("config_id", wxChatWay.getStr("config_id"));
		String str = OpenUtil.call(appId, API_ID_CHAT_WAY_DEL, wwxParam);
		
		// 本地数据库
		JSONObject obj = JSONUtil.parseObj(str);
		if (obj.getInt("errcode") == 0) {
			Db.delete(ds, wxChatWay);
		} else {
			throw new HtException("删除加入群聊企微接口返回错误：" + obj.getStr("errmsg"));
		}
	}
	
	/**
	 * 新增获客链接
	 * @param ds 数据源
	 * @param appId 应用ID
	 * @param positionId 渠道广告位ID
	 * @param positionName 渠道广告位名称
	 * @param state 渠道广告位自定义渠道
	 * @param ids 接粉组关联ID列表
	 */
	private static String addWithCustomerLink(DataSource ds, String appId, String positionId,
			String positionName, String state, List<String> ids) {
		String oldLinkId = Db.createSqlParser("wx_customer_link").select("link_id")
				.where("position_id", positionId).val(ds);
		if (StrUtil.isNotBlank(oldLinkId)) {
			throw new HtException("获客链接已存在！");
		}
		
		// 调用企微接口
		JSONObject wwxParam = JSONUtil.createObj();
		wwxParam.set("link_name", positionName);
		wwxParam.set("range.user_list", ids);
		wwxParam.set("skip_verify", true);
		String str = OpenUtil.call(appId, API_ID_CUSTOMER_LINK_ADD, wwxParam);
		
		// 本地数据库
		String linkId = null;
		JSONObject obj = JSONUtil.parseObj(str);
		if (obj.getInt("errcode") == 0) {
			JSONObject wxLink = obj.getJSONObject("link");
			Entity wxCustomerLink = Db.createEntity("wx_customer_link");
			wxCustomerLink.set("position_id", positionId);
			wxCustomerLink.set("state", state);
			wxCustomerLink.set("link_name", positionName);
			wxCustomerLink.set("appid", appId);
			wxCustomerLink.set("skip_verify", 1);
			linkId = wxLink.getStr("link_id");
			wxCustomerLink.set("link_id", linkId);
			wxCustomerLink.set("url", wxLink.getStr("url"));
			Db.insert(ds, wxCustomerLink);
		} else if (obj.getInt("errcode") == 41054) {
			throw new HtException("成员需要是已激活的成员，即成员至少登录过企业微信，且已实名认证！");
		} else {
			throw new HtException("新增获客链接企微接口返回错误：" + obj.getStr("errmsg"));
		}

		return linkId;
	}
	
	/**
	 * 修改获客链接
	 * @param ds 数据源
	 * @param appId 应用ID
	 * @param positionId 渠道广告位ID
	 * @param positionName 渠道广告位名称
	 * @param state 渠道广告位自定义渠道
	 * @param ids 接粉组关联ID列表
	 */
	private static void editWithCustomerLink(DataSource ds, String appId, String positionId, String positionName, 
			String state, List<String> ids) {
		String linkId = Db.createSqlParser("wx_customer_link").select("link_id")
				.where("position_id", positionId).val(ds);
		if (StrUtil.isBlank(linkId)) {
			throw new HtException("获客链接不存在！");
		}
		
		// 调用企微接口
		JSONObject wwxParam = JSONUtil.createObj();
		wwxParam.set("link_id", linkId);
		wwxParam.set("range.user_list", ids);
		String str = OpenUtil.call(appId, API_ID_CUSTOMER_LINK_EDIT, wwxParam);
		
		// 本地数据库
		JSONObject obj = JSONUtil.parseObj(str);
		if (obj.getInt("errcode") == 0) {
			Entity wxCustomerLink = Db.createEntity("wx_customer_link");
			wxCustomerLink.set("state", state);
			wxCustomerLink.set("appid", appId);
			wxCustomerLink.set("link_name", positionName);
			Db.insert(ds, wxCustomerLink);
		} else if (obj.getInt("errcode") == 41054) {
			throw new HtException("成员需要是已激活的成员，即成员至少登录过企业微信，且已实名认证！");
		} else {
			throw new HtException("修改获客链接企微接口返回错误：" + obj.getStr("errmsg"));
		}
	}
	
	/**
	 * 删除获客链接
	 * @param ds 数据源
	 * @param appId 应用ID
	 * @param positionId 渠道广告位ID
	 */
	private static void delWithCustomerLink(DataSource ds, String appId, String positionId) {
		Entity wxCustomerLink = Db.createSqlParser("wx_customer_link")
				.where("position_id", positionId).findOne(ds);
		if (wxCustomerLink == null) {
			return ;
		}
		
		// 调用企微接口，删除
		JSONObject wwxParam = JSONUtil.createObj().set("link_id", wxCustomerLink.getStr("link_id"));
		String str = OpenUtil.call(appId, API_ID_CUSTOMER_LINK_DEL, wwxParam);
		
		// 本地数据库
		JSONObject obj = JSONUtil.parseObj(str);
		if (obj.getInt("errcode") == 0) {
			Db.delete(ds, wxCustomerLink);
		} else {
			throw new HtException("删除获客链接企微接口返回错误：" + obj.getStr("errmsg"));
		}
	}
}
